﻿using System;
using System.Windows.Forms;
using System.Xml;
using UIShell.MessageBusService;
using UIShell.OSGi;
using Pasys.PresentationCore.Utility;
using Activator = System.Activator;

namespace Pasys.PresentationCore.WinForms
{
    public class ToolBarCommand : ToolStripMenuItem, ICloneable, IFindOwnerForm
    {
        public string CommandName { get; private set; }
        private readonly XmlNode node;
        private readonly IBundle owner;
        private readonly bool createCommand;
        private CommandStatusMonitor _statusMonitor;
        private Type eventType;
        private object menuCommand; //ICommand or IViewProvider

        public ILayoutViewProxyContainer FindOwnerForm()
        {
            ILayoutViewProxyContainer containner=null;
            if (this.OwnerItem != null)
            {
                containner= this.OwnerItem.Owner.FindForm() as ILayoutViewProxyContainer;
            }
            else if (this.Owner!=null)
            {
                containner= this.Owner.FindForm() as ILayoutViewProxyContainer;
            }

            if (containner == null)
            {
                containner = BundleRuntime.Instance.GetFirstOrDefaultService<ILayoutViewProxyContainer>();
            }

            return containner;
            //Guard.ArgumentNotNullOrEmptyString(f.Text, "FindForm");
        }

        public ToolBarCommand(XmlNode node, IBundle owner, bool createCommand)
        {
            RightToLeft = RightToLeft.Inherit;
            this.node = node;
            this.owner = owner;
            this.createCommand = createCommand;
            if (createCommand)
            {
                LoadClass();
            }

            if (Image == null)
            {
                string icon = XmlUtility.ReadAttribute(node, "icon");
                if (!string.IsNullOrEmpty(icon))
                {
                    Image = ResourcesUtility.TryGetBitmap(owner.LoadResource(icon, ResourceLoadMode.ClassSpace));
                }
            }



            Text = XmlUtility.ReadAttribute(node, "text");
            ToolTipText = XmlUtility.ReadAttribute(node, "tooltip");
            CommandName = XmlUtility.ReadAttribute(node, "command");

            var enabled = XmlUtility.ReadAttribute(node, "enabled");
            if (!string.IsNullOrEmpty(enabled))
            { 
                bool bl=false;
                if (bool.TryParse(enabled, out bl))
                {
                    Enabled = bl;
                }
            }
            if (!string.IsNullOrEmpty(CommandName))
            {
                _statusMonitor = new CommandStatusMonitor(CommandName, setEnable, setVisible);
            }

            var groupStrs = XmlUtility.ReadAttribute(node, "group");
            if (groupStrs.Length > 0)
            {
                var groups = groupStrs.Split(new char[] { ',' });
                foreach (var g in groups)
                {
                    if (g.Trim().Length == 0)
                        break;
                    var sgm = new CommandGroupStatusMonitor(g.Trim(), setEnable, setVisible);
                }
            }
        }

        private void setEnable(object sender,bool enable)
        {
            var findObj = sender as IFindOwnerForm;
            if (findObj != null  && findObj.FindOwnerForm() != this.FindOwnerForm())
            {
                return;
            }
            this.Enabled = enable;
        }

        private void setVisible(object sender, bool visible)
        {
            var findObj = sender as IFindOwnerForm;
            if (findObj != null && findObj.FindOwnerForm() != this.FindOwnerForm())
            {
                return;
            }
            this.Visible = visible;
        }

        private void LoadClass()
        {
            string classType = XmlUtility.ReadAttribute(node, "class");
            if (menuCommand == null && !string.IsNullOrEmpty(classType))
            {
                menuCommand = Activator.CreateInstance(owner.LoadClass(classType));
            }
            string commandType = XmlUtility.ReadAttribute(node, "event");
            if (eventType == null && !string.IsNullOrEmpty(commandType))
            {
                eventType = owner.LoadClass(commandType);
            }
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            if (menuCommand == null || eventType == null)
            {
                LoadClass();
            }
            //1,Handle ICommand
            if (menuCommand != null)
            {
                var cmd = menuCommand as ICommand;
                if (cmd != null)
                {
                    cmd.Run(this);
                }
                var viewProvider = menuCommand as IPersistViewProvider;
                if (viewProvider != null)
                {
                    IShellLayoutViewProxy shellLayoutView = null;
                    var f = this.FindOwnerForm() as ILayoutViewProxyContainer;
                    if (f != null)
                    {
                        shellLayoutView = f.LayoutViewProxy;
                    }
                    if (shellLayoutView == null)
                    {
                        shellLayoutView = BundleRuntime.Instance.GetFirstOrDefaultService<IShellLayoutViewProxy>();
                    }
                    viewProvider.Onwer = shellLayoutView.Owner.FindForm();
                    shellLayoutView.Show(viewProvider);
                    //if (viewProvider.ViewInfo == null)
                    //{
                    //    shellLayoutView.Show(viewProvider.View);
                    //}
                    //else
                    //{
                    //    shellLayoutView.Show(viewProvider.View, viewProvider.ViewInfo);
                    //}
                }
            }

            //2,Handle command name
            if (!string.IsNullOrEmpty(CommandName))
            {
                var commandService = BundleRuntime.Instance.GetFirstOrDefaultService<ICommandBusService>();
                commandService.PublicCommand(this,CommandName);
            }
            //3,Handle event bus
            if (eventType != null)
            {
                var service = BundleRuntime.Instance.GetFirstOrDefaultService<IMessageBusService>();
                service.Publish(eventType, Activator.CreateInstance(eventType));
            }
        }

        #region IClone

        public object Clone()
        {
            ToolBarCommand tb = new ToolBarCommand(this.node.Clone(), this.owner, this.createCommand);
            return tb;
        }

        #endregion
    }
}